package mysql

import (
	"fmt"
	"gitee.com/dreamwood/ez"
)

type Creator struct {
	AppName    string          `json:"appName"`
	Table      *Table          `json:"table"`
	Fields     []FieldItem     `json:"fields"`
	Model      string          `json:"model"` //数据模型，特殊模型需要使用该字段，比如tree
	SafeDelete bool            `json:"safeDelete"`
	SrcDirs    map[string]bool `json:"srcDirs"`
}

func NewTable(name string, cnName string, path string) *Creator {
	c := new(Creator)
	t := new(Table)
	t.Name = name
	t.Path = path
	t.CnName = cnName
	c.Table = t
	c.Fields = make([]FieldItem, 0)
	return c
}

func (c *Creator) GetTable() *Table {
	return c.Table
}
func (c *Creator) SetName(name string) *Table {
	c.Table.Name = name
	return c.Table
}

func (c *Creator) SetCnName(cnName string) *Table {
	c.Table.CnName = cnName
	return c.Table
}

func (c *Creator) SetPath(path string) *Table {
	c.Table.Path = path
	return c.Table
}

func (c *Creator) IsTree() *Table {
	c.Model = "tree"
	return c.Table
}

func (c *Creator) AddText(name string, label string) *Text {
	item := new(Text)
	item.Name = name
	item.CnName = label
	item.DefaultValue = ""
	item.Length = "255"
	item.Nullable = true
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddArt(name string, label string) *Art {
	item := new(Art)
	item.Name = name
	item.CnName = label
	item.DefaultValue = ""
	item.Nullable = true
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddJson(name string, label string) *Json {
	item := new(Json)
	item.Name = name
	item.CnName = label
	item.DefaultValue = ""
	item.Nullable = true
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddInt(name string, label string) *Int {
	item := new(Int)
	item.Name = name
	item.CnName = label
	item.DefaultValue = "0"
	item.Nullable = true
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddBool(name string, label string) *Bool {
	item := new(Bool)
	item.Name = name
	item.CnName = label
	item.Nullable = true
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddFloat(name string, label string) *Float {
	item := new(Float)
	item.Name = name
	item.CnName = label
	item.DefaultValue = "0"
	item.Nullable = true
	item.SetDecimals(4)
	item.SetDigits(12)
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddDateTime(name string, label string) *DateTime {
	item := new(DateTime)
	item.Name = name
	item.CnName = label
	item.DefaultValue = "0"
	item.Nullable = true
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddManyToOne(name string, label string, src string) *ManyToOne {
	item := new(ManyToOne)
	item.Table = *c.Table
	item.Name = name
	item.CnName = label
	item.DefaultValue = "0"
	item.Nullable = true
	item.Fk = fmt.Sprintf("%sId", ez.Ucfirst(name))
	item.SetSrc(src)
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddOneToMany(name string, label string, src string) *OneToMany {
	item := new(OneToMany)
	item.Table = *c.Table
	item.Name = name
	item.CnName = label
	item.DefaultValue = "0"
	item.Nullable = true
	item.Ref = fmt.Sprintf("%s", ez.Ucfirst(name))
	item.SetSrc(src)
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddOneToOne(name string, label string, src string) *OneToOne {
	item := new(OneToOne)
	item.Table = *c.Table
	item.Name = name
	item.CnName = label
	item.DefaultValue = "0"
	item.Nullable = true
	item.SetSrc(src)
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddManyToMany(name string, label string, src string) *ManyToMany {
	item := new(ManyToMany)
	item.Table = *c.Table
	item.Name = name
	item.CnName = label
	item.DefaultValue = "0"
	item.Nullable = true
	item.SetSrc(src)
	//item.SetSrcDir(c.Table.Path)
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddFile(name string, label string) *File {
	item := new(File)
	item.Name = name
	item.CnName = label
	item.DefaultValue = ""
	item.Nullable = false
	c.Fields = append(c.Fields, item)
	return item
}

func (c *Creator) AddFiles(name string, label string) *Files {
	item := new(Files)
	item.Name = name
	item.CnName = label
	item.DefaultValue = ""
	item.Nullable = false
	c.Fields = append(c.Fields, item)
	return item
}

// 常用的二次封装
func (c *Creator) AddCreateAt() *DateTime {
	return c.AddDateTime("createAt", "创建时间").SetIsAutoNowAdd(true)
}
func (c *Creator) AddUpdateAt() *DateTime {
	return c.AddDateTime("updateAt", "更新时间").SetIsAutoNowAdd(true).SetIsAutoNow(true)
}
func (c *Creator) AddCreateBy() *Int {
	return c.AddInt("createBy", "创建人")
}
func (c *Creator) AddOwner() *Int {
	return c.AddInt("owner", "所有人")
}
func (c *Creator) AddName() *Text {
	return c.AddText("name", "名称")
}
func (c *Creator) AddTitle() *Text {
	return c.AddText("title", "标题")
}
func (c *Creator) AddContent() *Art {
	return c.AddArt("content", "内容")
}
func (c *Creator) AddLock() *Bool {
	return c.AddBool("isLock", "是否锁定")
}
func (c *Creator) AddDelete() *Bool {
	c.SafeDelete = true
	c.AddDateTime("deleteAt", "删除时间")
	return c.AddBool("isDelete", "是否删除")
}
func (c *Creator) AddSort() *Int {
	return c.AddInt("sort", "排序")
}
func (c *Creator) AddState() *Int {
	return c.AddInt("state", "状态")
}
func (c *Creator) AddCode() *Text {
	return c.AddText("code", "编码")
}
func (c *Creator) LoadStatus() *Creator {
	c.AddText("color", "字体颜色")
	c.AddText("background", "背景颜色")
	c.AddText("group", "分组")
	c.AddText("step", "阶段标识")
	c.AddText("warn", "警告标识")
	return c
}
func (c *Creator) LoadTree() *Creator {
	//设置为分类树模型
	c.IsTree()

	c.AddSort()

	//Parent类型，领接表
	c.AddManyToOne("parent", "上级", c.Table.Name)
	//Left & Right ,预排序
	c.AddInt("l", "左边界")
	c.AddInt("r", "右边界")
	c.AddInt("level", "层级")
	//Link,文本Link查询
	c.AddText("link", "绑定关系")

	//操作记录提示
	c.AddCreateAt()
	c.AddUpdateAt()

	//安全删除
	c.AddDelete()
	return c
}

func (c *Creator) LoadDependence() *Creator {
	c.AddInt("outId", "outId")
	c.AddText("outSrc", "outSrc")
	return c
}
func (c *Creator) Generate() {
	Init(c)
}

func (c *Creator) 中文测试() {
	Init(c)
}
